/**
 * Copyright (c) 2011 Basil Shikin, VintageRadio Project
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.vintagephone.view.opengl.shapes;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

/**
 * This is a base for an OpenGL shape
 * 
 * @author Basil Shikin
 *
 */
public abstract class ShapeBase 
{
	private final static float[] s_defaultColor = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
	
	protected static int X = 0;
	protected static int Y = 1;
	protected static int Z = 2;
	
	private FloatBuffer m_vertices = null;
	
	private ShortBuffer m_indices  = null;
	private int 		m_indiciesSize = 0;
	
	private FloatBuffer m_colors = null;

	/**
	 * Draw the shape.
	 * 
	 * @param gl Open GL context to use
	 */
	public void draw(GL10 gl) 
	{
//		gl.glFrontFace(GL10.GL_CCW);
//		gl.glEnable(GL10.GL_CULL_FACE);

//		gl.glCullFace(GL10.GL_BACK);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		
		// Specifies the location and data format of an array of vertex
		// coordinates to use when rendering.
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_vertices);
		
		// Set flat color
		gl.glColor4f(s_defaultColor[0], s_defaultColor[1], s_defaultColor[2], s_defaultColor[3]);
		
		//	Smooth color
		if (m_colors != null) 
		{
			// Enable the color array buffer to be used during rendering.
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
			gl.glColorPointer(4, GL10.GL_FLOAT, 0, m_colors);
		}

		gl.glDrawElements(GL10.GL_TRIANGLES, m_indiciesSize, GL10.GL_UNSIGNED_SHORT, m_indices);
		
		gl.glColor4f(1f, 0f, 0f, 1f);
		gl.glDrawElements(GL10.GL_LINE_LOOP, m_indiciesSize, GL10.GL_UNSIGNED_SHORT, m_indices);
		
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//		gl.glDisable(GL10.GL_CULL_FACE);
	}
	
	protected abstract void loadShape();
	
	/**
	 * Set the vertices.
	 * 
	 * @param vertices
	 */
	protected void setVertices(float... vertices) 
	{
		// a float is 4 bytes, therefore we multiply the number if
		// vertices with 4.
		ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
		vbb.order(ByteOrder.nativeOrder());
		
		m_vertices = vbb.asFloatBuffer();
		m_vertices.put(vertices);
		m_vertices.position(0);
	}

	/**
	 * Set the indices.
	 * 
	 * @param indices
	 */
	protected void setIndices(int... indices) 
	{
		short[] shorts = new short[ indices.length ];
		for ( int i = 0; i < indices.length; i++ ) shorts[i] = (short)indices[i];
		
		setIndices( shorts );
	}
	
	/**
	 * Set the indices.
	 * 
	 * @param indices
	 */
	protected void setIndices(short... indices) 
	{
		// short is 2 bytes, therefore we multiply the number if
		// vertices with 2.
		ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
		ibb.order(ByteOrder.nativeOrder());
		
		m_indices = ibb.asShortBuffer();
		m_indices.put(indices);
		m_indices.position(0);
		
		m_indiciesSize = indices.length;
	}

	protected void setColors(float... colors) 
	{
		// float has 4 bytes.
		final ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
		cbb.order(ByteOrder.nativeOrder());
		
		m_colors = cbb.asFloatBuffer();
		m_colors.put(colors);
		m_colors.position(0);
	}
	

}
